package com.shanzmoo.core.service.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.shanzmoo.base.constant.MallOrderStatus;
import com.shanzmoo.core.service.IMallOrderRedisService;
import com.shanzmoo.core.util.RedisCoreKeyUtils;
import com.shanzmoo.db.mall.entity.MallOrderDetailEntity;
import com.shanzmoo.db.mall.entity.MallOrderEntity;
import com.shanzmoo.db.mall.service.IMallOrderDetailService;
import com.shanzmoo.db.mall.service.IMallOrderService;
import com.shanzmoo.db.order.entity.dto.MallOrderDeatilRedisDTO;
import com.shanzmoo.db.order.entity.dto.MallOrderRedisDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 商城订单缓存操作 实现类
 * @author Gzhao 2020/12/25
 */
@Slf4j
@Service
public class MallOrderRedisServiceImpl implements IMallOrderRedisService {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private IMallOrderService mallOrderService;

    @Autowired
    private IMallOrderDetailService mallOrderDetailService;

    @Override
    public void refreshAllOrderRedis() {
        // 订单信息
        List<MallOrderEntity> allOrderList = mallOrderService.list(
                new QueryWrapper<MallOrderEntity>()
                        .eq("deleted", false)
                        .ne("status", MallOrderStatus.CLOSED)
        );

        // 基础订单数据
        String allOrderListKey = RedisCoreKeyUtils.installAllOrderListKey();
        stringRedisTemplate.delete(allOrderListKey);
        for (MallOrderEntity mallOrderEntity : allOrderList) {
            MallOrderRedisDTO redisDTO = JSON.parseObject(JSON.toJSONString(mallOrderEntity), MallOrderRedisDTO.class);

            stringRedisTemplate.opsForHash().put(allOrderListKey, String.valueOf(mallOrderEntity.getId()), JSON.toJSONString(redisDTO));
        }

        // 用户订单
        String memberOrderListKey = RedisCoreKeyUtils.installMemberOrderListKey();
        stringRedisTemplate.delete(memberOrderListKey);
        Map<Integer, List<MallOrderEntity>> memberMap = allOrderList.stream().collect(Collectors.groupingBy(MallOrderEntity::getMemberId));
        for (Integer memberId : memberMap.keySet()){
            List<MallOrderEntity> memberOrderList = memberMap.get(memberId);
            List<Integer> memberOrderIds = memberOrderList.stream().map(MallOrderEntity::getId).collect(Collectors.toList());
            stringRedisTemplate.opsForHash().put(memberOrderListKey, String.valueOf(memberId), JSON.toJSONString(memberOrderIds));
        }

        // 订单详情
        List<Integer> orderIds = allOrderList.stream().map(MallOrderEntity::getId).collect(Collectors.toList());
        List<MallOrderDetailEntity> allOrderDetailList = mallOrderDetailService.list(
                new QueryWrapper<MallOrderDetailEntity>()
                        .eq("deleted", false)
                        .in("order_id", orderIds)
        );
        Map<Integer, List<MallOrderDetailEntity>> orderDetailMap = allOrderDetailList.stream()
                .collect(Collectors.groupingBy(MallOrderDetailEntity::getOrderId));

        String orderDetailListKey = RedisCoreKeyUtils.installOrderDetailListKey();
        stringRedisTemplate.delete(orderDetailListKey);
        for (Integer orderId : orderDetailMap.keySet()){
            List<MallOrderDetailEntity> orderDetailList = orderDetailMap.get(orderId);
            List<MallOrderDeatilRedisDTO> orderDetailRedisList = JSON.parseArray(JSON.toJSONString(orderDetailList), MallOrderDeatilRedisDTO.class);

            stringRedisTemplate.opsForHash().put(orderDetailListKey, String.valueOf(orderId), JSON.toJSONString(orderDetailRedisList));
        }
    }

    @Override
    public void addOneOrderRedis(MallOrderEntity orderEntity, List<MallOrderDetailEntity> orderDetailList) {
        // 1.订单信息
        String allOrderListKey = RedisCoreKeyUtils.installAllOrderListKey();

        MallOrderRedisDTO redisDTO = JSON.parseObject(JSON.toJSONString(orderEntity), MallOrderRedisDTO.class);
        stringRedisTemplate.opsForHash().put(allOrderListKey, String.valueOf(orderEntity.getId()), JSON.toJSONString(redisDTO));

        // 2.用户订单
        String memberOrderListKey = RedisCoreKeyUtils.installMemberOrderListKey();
        String memberOrderListStr = (String)stringRedisTemplate.opsForHash().get(memberOrderListKey, String.valueOf(orderEntity.getMemberId()));

        List<Integer> memberOrderIds;
        if (StrUtil.isNotBlank(memberOrderListStr)){

            memberOrderIds = JSON.parseArray(memberOrderListStr, Integer.class);
        } else {

            memberOrderIds = new ArrayList<>();
        }
        memberOrderIds.add(orderEntity.getId());
        stringRedisTemplate.opsForHash().put(memberOrderListKey, String.valueOf(orderEntity.getMemberId()), JSON.toJSONString(memberOrderIds));

        // 3.订单详情
        List<MallOrderDeatilRedisDTO> orderDetailRedisList = JSON.parseArray(JSON.toJSONString(orderDetailList), MallOrderDeatilRedisDTO.class);
        stringRedisTemplate.opsForHash().put(RedisCoreKeyUtils.installOrderDetailListKey(), String.valueOf(orderEntity.getId()),
                JSON.toJSONString(orderDetailRedisList));
    }

    @Override
    public void removeMemberOrder(Integer orderId, Integer memberId) {
        // 1.订单信息
        String allOrderListKey = RedisCoreKeyUtils.installAllOrderListKey();
        stringRedisTemplate.opsForHash().delete(allOrderListKey, String.valueOf(orderId));

        // 2.用户订单
        String memberOrderListKey = RedisCoreKeyUtils.installMemberOrderListKey();
        String memberOrderListStr = (String)stringRedisTemplate.opsForHash().get(memberOrderListKey, String.valueOf(memberId));

        if (StrUtil.isNotBlank(memberOrderListStr)){
            List<Integer> memberOrderIds = JSON.parseArray(memberOrderListStr, Integer.class);
            memberOrderIds.remove(orderId);
            stringRedisTemplate.opsForHash().put(memberOrderListKey, String.valueOf(memberId), JSON.toJSONString(memberOrderIds));
        }

        // 3.订单详情
        stringRedisTemplate.opsForHash().delete(RedisCoreKeyUtils.installOrderDetailListKey(), String.valueOf(orderId));

    }

    @Override
    public void updateOrder(Integer orderId) {
        MallOrderEntity mallOrderEntity = mallOrderService.getById(orderId);
        MallOrderRedisDTO redisDTO = JSON.parseObject(JSON.toJSONString(mallOrderEntity), MallOrderRedisDTO.class);

        stringRedisTemplate.opsForHash().put(RedisCoreKeyUtils.installAllOrderListKey(), String.valueOf(orderId), JSON.toJSONString(redisDTO));
    }
}
